<?php

namespace weixinpay;
if (!defined('WXPAY_ROOT')) {
    define('WXPAY_ROOT', dirname(__FILE__) . '/');
}
//require_once WXPAY_ROOT."lib/WxPayApi.php";
//require_once WXPAY_ROOT."lib/NativePay.php";
require_once WXPAY_ROOT."lib/WxPay.Data.php";
require_once WXPAY_ROOT."lib/WxPay.NativePay.php";


class WxPay
{
	public $errCode = 40001;
	public $errMsg = "no access";
	
	protected $appid='';
	protected $appsecret='';
	protected $mch_id='';
	protected $key='';	
	protected $cert_path='';
	
	public function __construct($options) {
		$this->appid = isset($options['appid'])?$options['appid']:'';
		$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';
		$this->mch_id = isset($options['mch_id'])?$options['mch_id']:'';
		$this->key = isset($options['key'])?$options['key']:'';
		if(!empty($options['cert_path'])){
			$this->cert_path = isset($options['cert_path'])?$options['cert_path']:'';	
		}	
	}
	
	protected function getConfig()
	{
		$options = array(
			'appid'=>$this->appid,
			'appsecret'=>$this->appsecret,
			'mch_id'=>$this->mch_id,
			'key'=>$this->key,
			'cert_path'=>$this->cert_path,
		);
		return $options;
	}
	
	public function JsapiPay($param)
	{
		$input = new \WxPayUnifiedOrder($this->getConfig());
		$input->SetTrade_type("JSAPI");
		$input->SetOpenid($param['openid']);
		$input->SetBody($param['body']);
		$input->SetOut_trade_no($param['out_trade_no']);
		$input->SetTotal_fee($param['total_fee']);		
		$input->SetNotify_url($param['notify_url']);
		if(!empty($param['attach'])){
			$input->SetAttach($param['attach']);	
		}	
		$api = new \WxPayApi($this->getConfig());
		$order = $api->unifiedOrder($input);		
		$jsApiParameters = $this->GetJsApiParameters($order);
		return $jsApiParameters;
	}
	
	public function QrcodePay($productId)
	{
		//$input = $this->getPostData($data,'NATIVE');
		$api = new \WxPayApi($this->getConfig());
		//$result = $api->unifiedOrder($input);
		//$notify = new \NativePay($this->getConfig());
		//$result = $notify->GetPayUrl($input);
		//return $result["code_url"];	
		
		$biz = new \WxPayBizPayUrl($this->getConfig());
		$biz->SetProduct_id($productId);
		$values = $api->bizpayurl($biz);
		$url = "weixin://wxpay/bizpayurl?" . $this->ArrayToUrl($values);
		return $url;
	}
			
	public function WxPayNotify($callback, $needSign=true)
	{				
		$msg = '';
		$api = new \WxpayApi($this->getConfig());
		$result = $api->notify($callback, $msg);		
		$reply = new \WxPayNotifyReply($this->getConfig());
		if($result == false){
			$reply->SetReturn_code("FAIL");
			$reply->SetReturn_msg($msg);
			$api->replyNotify($reply->ToXml());			
			return false;
		} else {			
			$reply->SetReturn_code("SUCCESS");
			$reply->SetReturn_msg("OK");
		}		
		if($needSign == true && $reply->GetReturn_code($return_code) == "SUCCESS")
		{
			$reply->SetSign();
		}
		$api->replyNotify($reply->ToXml());			
	}
	public function Queryorder($transaction_id)
	{
		$api = new \WxpayApi($this->getConfig());
		$input = new \WxPayOrderQuery($this->getConfig());
		$input->SetTransaction_id($transaction_id);
		$result = $api->orderQuery($input);		
		if(array_key_exists("return_code", $result)
			&& array_key_exists("result_code", $result)
			&& $result["return_code"] == "SUCCESS"
			&& $result["result_code"] == "SUCCESS")
		{
			return true;
		}
		return false;
	}
	
	public function Refund($data)
	{
		$input = new \WxPayRefund($this->getConfig());
		$input->SetTransaction_id($data["transaction_id"]);
		$input->SetOut_refund_no($data["out_refund_no"]);
		$input->SetTotal_fee($data["total_fee"]);
		$input->SetRefund_fee($data["refund_fee"]);
		if(!empty($data["notify_url"])){
			$input->SetNotify_url($data["notify_url"]);		
		}		
		$input->SetOp_user_id($this->mch_id);
		$api = new \WxPayApi($this->getConfig());
		return $api->refund($input);
	}
			
	private function GetJsApiParameters($UnifiedOrderResult)
	{
		if(!array_key_exists("appid", $UnifiedOrderResult)
		|| !array_key_exists("prepay_id", $UnifiedOrderResult)
		|| $UnifiedOrderResult['prepay_id'] == "")
		{
			throw new \WxPayException("参数错误");
		}
		$jsapi = new \WxPayJsApiPay($this->getConfig());
		$jsapi->SetAppid($UnifiedOrderResult["appid"]);
		$timeStamp = time();
		$jsapi->SetTimeStamp("$timeStamp");
		$jsapi->SetNonceStr(\WxPayApi::getNonceStr());
		$jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
		$jsapi->SetSignType("MD5");
		$jsapi->SetPaySign($jsapi->MakeSign());
		//$parameters = json_encode($jsapi->GetValues());
		//return $parameters;
		return $jsapi->GetValues();
	}	
	public function getPostData($params,$trade_type = 'JSAPI')
    {
        $input  = new \WxPayUnifiedOrder($this->getConfig());        
        $input->SetTrade_type($trade_type);        
        $input->SetBody($params['body']);
        $input->SetTotal_fee($params['total_fee']);        
        $input->SetOut_trade_no($params['out_trade_no']);
		
		if($trade_type != 'NATIVE'){
			$input->SetOpenid($params['openid']);				
		}	
		if(!empty($params['notify_url'])){
			$input->SetNotify_url($params['notify_url']);			
		}
		if(!empty($params['attach'])){
			$input->SetAttach($params['attach']);			
		}
		
		if($trade_type == 'NATIVE' && !empty($params['product_id'])){
			$input->SetProduct_id($params['product_id']);				
		}
        return $input;
    }
	
	/**
	 * 
	 * 参数数组转换为url参数
	 * @param array $urlObj
	 */
	private function ArrayToUrl($urlObj)
	{
		$buff = "";
		foreach ($urlObj as $k => $v)
		{
			$buff .= $k . "=" . $v . "&";
		}
		
		$buff = trim($buff, "&");
		return $buff;
	}
}
